#ifndef __DEKE_MOTOR_H__
#define __DEKE_MOTOR_H__

#include "stdint.h"
#include "tim.h"
#include "PIDcontroller.h"

#define SPEED_COMPENSATION 1.1f // 速度补偿系数,用于电机速度整体调整，适用于不同的车由于重量不同而导致需要的PWM值不同
#define ENCODER_ONE_STANDARD 572 // 标准的一圈编码器的脉冲数

struct MotorSpeedPWMInfo{
  int16_t speed;
  int16_t PWM;
};

enum MotorMode
{
    MOTOR_MODE_Direct = 0,
    MOTOR_MODE_SPEED = 1,
};

enum MotorDirection
{
    MOTOR_NOMRAL = 0,
    MOTOR_REVERSE,
};

typedef enum {
    Left_wheel,
    Right_wheel,
} Position;

typedef struct _deke_config
{
    TIM_HandleTypeDef* PWM_handle;      // 发出PWM波形的定时器句柄
    TIM_HandleTypeDef* encoder_handle;  // 获取编码器值的句柄
    struct _deke_motor* other_motor_encoder;    // 当此电机没有编码器时，可以借用其他的电机编码器
    uint32_t tim_channel_1;             // PWM通道一
    uint32_t tim_channel_2;             // PWM通道二

} DEKE_CONFIG_T;

typedef struct _deke_motor
{
    DEKE_CONFIG_T* config;              // 定时器的相关配置
    PIDInstance* pid_handle;             // pid的句柄
    enum MotorMode motor_mode;          // 电机模式
    enum MotorDirection direction;      // 电机方向
    Position wheel_position;            // 电机位置,判断是左电机还是右电机
    uint16_t encoder_one_round;         // 编码器转一圈实际的脉冲值

    int16_t speed;                      // 速度
    int16_t encoder;                    // 编码器值
    uint16_t PWM;                       // PWM值

    uint16_t lastError;
    uint8_t errorNum;
    uint8_t lastFlag;
    uint8_t reverseFlag;

    struct _deke_motor* next;           // 下一个节点
} DEKE_TypeDef;


void DEKE_Init(DEKE_TypeDef* this,DEKE_CONFIG_T* configs,enum MotorMode motor_mode,Position wheel_position,enum MotorDirection direction,uint16_t encoder_one_round);
void DEKE_SetSpeed(DEKE_TypeDef* this, int16_t speed);
void DEKE_SetRealSpeed(DEKE_TypeDef* this,int16_t PWM);
int16_t DEKE_GetMotorPWM(DEKE_TypeDef* this);
int16_t getMotorPWMBySpeed(struct MotorSpeedPWMInfo motorSpeedPWMInfo[], uint8_t size,int16_t speed);
float getMotorSpeedByPWM(struct MotorSpeedPWMInfo motorSpeedPWMInfo[], uint8_t size,int16_t PWM);
void DEKE_SpeedAdjustment_PID(void);
void DEKE_ChangeMode(DEKE_TypeDef *this,enum MotorMode motor_mode);
void DEKE_MotorStop(DEKE_TypeDef *this);
enum MotorMode DEKE_getMotorRunMode(DEKE_TypeDef *this);
uint8_t DEKE_Encoder_Task(void);
int16_t DEKE_Get_encoder(DEKE_TypeDef *this);

#endif // !__DEKE_MOTOR_H__
